package com.mmd.manage.service.impl;

import com.mmd.bean.CODE;
import com.mmd.bean.PageBean;
import com.mmd.bean.UserLoginContext;
import com.mmd.common.entity.*;
import com.mmd.common.enums.UserStatusEnums;
import com.mmd.exception.GameException;
import com.mmd.manage.dao.*;
import com.mmd.manage.service.UserService;
import com.mmd.manage.vo.AdminUserVo;
import com.mmd.manage.vo.ResetPasswordDto;
import com.mmd.manage.vo.UserDto;
import com.mmd.manage.vo.UserEo;
import com.mmd.redis.RedisKey;
import com.mmd.redis.RedisManager;
import com.mmd.utils.CookieTools;
import com.mmd.utils.ObfuseTableBase64;
import com.mmd.utils.RandomUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserDao userDao;
    @Autowired
    private MmdUserRoleDao mmdUserRoleDao;
    @Autowired
    private MmdRoleDao mmdRoleDao;
    @Autowired
    private MmdRoleMenuDao mmdRoleMenuDao;
    @Autowired
    private MmdMenuDao mmdMenuDao;

    @Override
    public Map<String, Object> login(String account, String pwd, HttpServletResponse response) {
        MmdUser user = userDao.getUserByAccount(account);
        if (user == null) {
            throw new GameException(new CODE(9999, "用户不存在"));
        }
        if (UserStatusEnums.auditfail.getCode().equals(user.getIsFree())) {
            throw new GameException(new CODE(9999, "审核不通过，请重新注册"));
        }
        if (UserStatusEnums.auditing.getCode().equals(user.getIsFree())) {
            throw new GameException(new CODE(9999, "审核中，请稍后再试"));
        }

        String md5Pwd = ObfuseTableBase64.encode(pwd);
        if (!md5Pwd.equals(user.getPassword()))
            throw new GameException(new CODE(9999, "密码错误，请重新输入"));
        if (user.getIsFree() == 1)
            throw new GameException(new CODE(9999, "账号已被冻结"));

        String token = RandomUtil.generateLowerString(8);
        UserLoginContext loginContext = new UserLoginContext();
        loginContext.setUid(user.getUid());
        loginContext.setAccount(user.getAccount());
        loginContext.setUserName(user.getUserName());
        loginContext.setIsFree(user.getIsFree());
        loginContext.setLevel(user.getLevel());
        loginContext.setUserLevel(user.getUserLevel());
        loginContext.setToken(token);
        RedisManager.set(RedisKey.ADMIN_TOKEN + token, loginContext, 6000);
        CookieTools.addCookie(response, "adminToken", token, 6000, null);

        List<MmdUserRole> mmdUserRoleList = mmdUserRoleDao.getRoleByUid(user.getUid());
        List<Map<String, Object>> menuList = new ArrayList<>();
        if (mmdUserRoleList != null){
            Set<Long> menuIdSet = new HashSet<>();
            for (MmdUserRole mmdUserRole : mmdUserRoleList) {
                List<MmdRoleMenu> mmdRoleMenuList = mmdRoleMenuDao.getMenuListByRole(mmdUserRole.getRoleId());
                for (MmdRoleMenu mmdRoleMenu : mmdRoleMenuList) {
                    menuIdSet.add(mmdRoleMenu.getMenuId());
                }
            }
            for (Long menuId : menuIdSet){
                MmdMenu mmdMenu = mmdMenuDao.getMenuById(menuId);
                if (mmdMenu != null) {
                    Map<String, Object> map = new HashMap<>();
                    map.put("menuId", mmdMenu.getMenuId());
                    map.put("menuName", mmdMenu.getMenuName());
                    menuList.add(map);
                }
            }
        }

        Map<String, Object> test = new HashMap<>();
        test.put("uid", user.getUid());
        test.put("userName", user.getUserName());
        test.put("cookieName", "adminToken");
        test.put("token", token);
        test.put("level", user.getLevel());
        test.put("companyName", user.getCompanyName());
        test.put("loginCount", user.getLoginCount());
        test.put("menuList", menuList);
        return test;
    }

    @Override
    public boolean logoff(HttpServletRequest request, HttpServletResponse response, String adminToken) {
        RedisManager.delete(RedisKey.ADMIN_TOKEN + adminToken);
        return true;
    }

    @Override
    public boolean register(UserEo user) {
//        if (StringUtils.isBlank(user.getAccount())) {
//            throw new GameException(new CODE(9999, "用户名不能为空"));
//        }

        //只校验已审核通过的电话号码唯一
//        MmdUser user1 = new MmdUser();
//        user1.setPhone(user.getAccount());
//        user1.setIsFree(UserStatusEnums.normal.getCode());
//        List<MmdUser> mmdUsers = userDao.selectByKeySelective(user1);
//        if (mmdUsers != null && mmdUsers.size() > 0) {
//            throw new GameException(new CODE(9999, "手机号码已注册"));
//        }

        if (StringUtils.isBlank(user.getMailAccount())) {
            throw new GameException(new CODE(9999, "邮箱不能为空"));
        }
        if (StringUtils.isBlank(user.getCompanyName())) {
            throw new GameException(new CODE(9999, "公司名称不能为空"));
        }

        if (userDao.getByCompanyName(null, user.getCompanyName()) > 0){
            throw new GameException(new CODE(9999, "该公司已注册，请勿重复注册"));
        }

        if (StringUtils.isBlank(user.getLocation())) {
            throw new GameException(new CODE(9999, "公司地址不能为空"));
        }
        if (StringUtils.isBlank(user.getLicenseImg())) {
            throw new GameException(new CODE(9999, "请上传营业执照"));
        }

        if (StringUtils.isBlank(user.getPassword()) || StringUtils.isBlank(user.getConfirmPwd())) {
            throw new GameException(new CODE(9999, "请设置密码"));
        }
        if (!user.getPassword().equals(user.getConfirmPwd())) {
            throw new GameException(new CODE(9999, "请确认密码是否一致"));
        }

        MmdUser inuser = new MmdUser();
        BeanUtils.copyProperties(user, inuser);
        String md5Pwd = ObfuseTableBase64.encode(user.getPassword());
//        inuser.setPhone(user.getAccount());
        inuser.setPassword(md5Pwd);
        inuser.setLevel("user");
        inuser.setUserLevel("D");
        inuser.setCreateTime(new Date());
        inuser.setIsFree(UserStatusEnums.auditing.getCode());
        inuser.setLicenseImg(user.getLicenseImg());
        inuser.setLoginCount(0L);

        userDao.insert(inuser);
        return true;
    }

    @Override
    public boolean audit(String account, Integer flag) {
        if (StringUtils.isBlank(account)) {
            throw new GameException(new CODE(9999, "用户名为空"));
        }
        MmdUser userByAccount = userDao.getUserByAccount(account);

        if (Objects.isNull(userByAccount)) {
            throw new GameException(new CODE(9999, "用户名不存在"));
        }
        MmdUser user1 = new MmdUser();
        user1.setUid(userByAccount.getUid());
        user1.setIsFree(flag);

        return userDao.updateByPrimaryKeySelective(user1) == 1;
    }


    @Override
    public boolean setLevel(String account, String userLevel) {
        MmdUser userByAccount = userDao.getUserByAccount(account);
        MmdUser user1 = new MmdUser();
        user1.setUid(userByAccount.getUid());
        user1.setUserLevel(userLevel);

        return userDao.updateByPrimaryKeySelective(user1) == 1;
    }

    @Override
    public boolean modifyPwd(UserEo user) {
        if (StringUtils.isBlank(user.getAccount())) {
            throw new GameException(new CODE(9999, "用户名为空"));
        }
        if (!user.getConfirmPwd().equals(user.getPassword())) {
            throw new GameException(new CODE(9999, "两次输入密码不一致"));
        }
        MmdUser userByAccount = userDao.getUserByAccount(user.getAccount());
        String newPwd = ObfuseTableBase64.encode(user.getPassword());

        MmdUser updateUser = new MmdUser();
        updateUser.setUid(userByAccount.getUid());
        updateUser.setPassword(newPwd);
        userDao.updateByPrimaryKeySelective(updateUser);

        return true;
    }

    @Override
    public List<MmdUser> userList(String companyName) {
        MmdUser user = new MmdUser();
        user.setLevel("user");
        user.setCompanyName(companyName);
        List<MmdUser> mmdUsers = userDao.selectByKeySelective(user);
        return mmdUsers;
    }

    @Override
    @Transactional
    public void addAdminUser(UserDto userDto) {
        if (StringUtils.isEmpty(userDto.getAccount())){
            throw new GameException(new CODE(9999, "账号不能为空"));
        }
        if (StringUtils.isEmpty(userDto.getPassword())){
            throw new GameException(new CODE(9999, "密码不能为空"));
        }
        if (userDao.getAccountNumber(userDto.getAccount()) > 0){
            throw new GameException(new CODE(9999, "账号已存在"));
        }

        MmdUser mmdUser = new MmdUser();
        mmdUser.setAccount(userDto.getAccount());
        mmdUser.setUserName(userDto.getAccount());
        mmdUser.setPassword( ObfuseTableBase64.encode(userDto.getPassword()));
        mmdUser.setLevel("admin");
        mmdUser.setIsFree(0);
        mmdUser.setLoginCount(0l);
        mmdUser.setCreateTime(new Date());
        userDao.insert(mmdUser);

        if (userDto.getRoleIds() != null){
            for (String roleIdStr : userDto.getRoleIds().split(",")) {
                MmdUserRole mmdUserRole = new MmdUserRole();
                mmdUserRole.setUid(mmdUser.getUid());
                mmdUserRole.setRoleId(Long.parseLong(roleIdStr));
                mmdUserRoleDao.insert(mmdUserRole);
            }
        }
    }

    @Override
    public PageBean<AdminUserVo> getUserPageList(int pageNo, int pageSize) {
        List<MmdUser> list = userDao.getAdminUserListPage((pageNo - 1) * pageSize , pageSize);
        List<AdminUserVo> resultList = list.stream().map(mmdUser -> {
            AdminUserVo adminUserVo = new AdminUserVo();
            adminUserVo.setUid(mmdUser.getUid());
            adminUserVo.setUserName(mmdUser.getUserName());
            adminUserVo.setIsFree(mmdUser.getIsFree());

            List<MmdUserRole> mmdUserRoleList = mmdUserRoleDao.getRoleByUid(mmdUser.getUid());
            if (mmdUserRoleList != null){
                String roleIds = "";
                String roleNames = "";
                int i = 0;
                for (MmdUserRole mmdUserRole : mmdUserRoleList) {
                    MmdRole mmdRole = mmdRoleDao.getRoleById(mmdUserRole.getRoleId());
                    if (mmdRole != null) {
                        roleIds = roleIds + mmdRole.getRoleId();
                        roleNames = roleNames + mmdRole.getRoleName();
                    }

                    if (i < mmdUserRoleList.size() - 1){
                        roleIds = roleIds + ",";
                        roleNames = roleNames + ",";
                    }

                    i++;
                }
                adminUserVo.setRoleIds(roleIds);
                adminUserVo.setRoleNames(roleNames);
            }
            return adminUserVo;
        }).collect(Collectors.toList());
        return new PageBean(resultList,userDao.getAdminUserListPageTotal(),pageSize,pageNo);
    }

    @Override
    public void isFree(long uid, int isFree) {
       MmdUser mmdUser = new MmdUser();
       mmdUser.setUid(uid);
       mmdUser.setIsFree(isFree);
       userDao.updateByPrimaryKeySelective(mmdUser);
    }

    @Override
    public void resetPassword(ResetPasswordDto resetPasswordDto) {
        MmdUser mmdUser = new MmdUser();
        mmdUser.setUid(resetPasswordDto.getUid());
        mmdUser.setPassword(ObfuseTableBase64.encode(resetPasswordDto.getPassword()));
        userDao.updateByPrimaryKeySelective(mmdUser);
    }

    @Override
    public void modifyUserInfo(MmdUser mmdUser) {
        if (mmdUser.getUid() == null){
            throw new GameException(new CODE(9999, "请选择客户"));
        }
        MmdUser update = new MmdUser();
        update.setUid(mmdUser.getUid());

        boolean isUpdate = false;
        if (StringUtils.isNotEmpty(mmdUser.getAccount())){
            MmdUser mmdUser1 = userDao.getUserByAccount(mmdUser.getAccount());
            if (mmdUser1 != null && mmdUser1.getUid() != mmdUser.getUid()){
                throw new GameException(new CODE(9999, "用户名已存在"));
            }
            update.setAccount(mmdUser.getAccount());
            isUpdate = true;
        }
        if (StringUtils.isNotEmpty(mmdUser.getUserName())){
            update.setUserName(mmdUser.getUserName());
            isUpdate = true;
        }
        if (StringUtils.isNotEmpty(mmdUser.getPhone())){
            update.setPhone(mmdUser.getPhone());
            isUpdate = true;
        }
        if (StringUtils.isNotEmpty(mmdUser.getCompanyName())){
            if (userDao.getByCompanyName(mmdUser.getUid(), mmdUser.getCompanyName()) > 0){
                throw new GameException(new CODE(9999, "公司名已存在"));
            }
            update.setCompanyName(mmdUser.getCompanyName());
            isUpdate = true;
        }
        if (StringUtils.isNotEmpty(mmdUser.getMailAccount())){
            update.setMailAccount(mmdUser.getMailAccount());
            isUpdate = true;
        }
        if (StringUtils.isNotEmpty(mmdUser.getRemark())){
            update.setRemark(mmdUser.getRemark());
            isUpdate = true;
        }

        if (isUpdate){
            userDao.updateByPrimaryKeySelective(update);
        }
    }
}
